import api from '../../api/index'
import common from "../../common/index";
import envConfig from '../../env'
import { ChatItemType, ChatStatusEnum } from '../../types/index';
import { createDialogueId } from '../../utils/util';
const app = getApp()
Component({
  data: {
    hasUserInfo: false,
    canIUseGetUserProfile: wx.canIUse('getUserProfile'),
    canIUseNicknameComp: wx.canIUse('input.type.nickname'),
    statusBarHeight: app.globalData.statusBarHeight,
    navBarHeight: app.globalData.navBarHeight,
    pcenterPageShow: false,
    summaryPageShow: false,
    uid: '',
    currentDirItem: {
      dir_id: '',
      dir_name: ''
    },
    cacheCurrentDirItem: {
      dir_id: '',
      dir_name: ''
    },
    currentFile: {},
    dirList: [],
    fileList: [],
    importantDirs: [], // 常用文件夹列表
    fieldNames: {
      text: 'dir_name',
      value: 'dir_id',
      children: 'children',
    },
    selectDirShow: false,
    isChangeDir: false,
    dialogueSheetShow: false,
    dialogueFile: null as any,
    dialogueModelList: ['Deepseek R1', '搜AINSPIRE', '搜全网', '搜智库'],
    activeDialogueModel: 'Deepseek R1',
    dialogueChatHistory: [] as ChatItemType[],
    dialogueTopicId: '',
    dialogueUploads: [] as Array<{name: string, extension: string}>,
    dialogueQuestion: '',
    dialogueConditionStatus: {
      r1: 1,
      aispire: 1,
      knowledge: 0,
      network: 0
    },
    dialogueScrollIntoView: '',
    dialogueMode: 'file',
    dialogueFolderFileIds: [] as string[]
  },
  lifetimes: {
    ready() {
      const user = common.getAppUserInfo()
      this.data.uid = user.uid
      this.setData({
        uid: user.uid
      })
      if (this.data.uid) {
        this.getDirFileList();
        this.getImportantDirs();
      }
    }
  },
  pageLifetimes: {
    show() {
      wx.showShareMenu({
        withShareTicket: true,
        menus: ['shareAppMessage', 'shareTimeline']
      })
    }
  },
  methods: {
    showPcenterPage() {
      this.setData({
        pcenterPageShow: true
      })
    },
    closePcenterPage() {
      this.setData({
        pcenterPageShow: false
      })
    },
    showSummaryPage(e: BaseEvent) {
      const index = e.currentTarget.dataset.index
      const file = this.data.fileList[index]
      this.setData({
        summaryPageShow: true,
        currentFile: file
      })
    },
    closeSummaryPage() {
      this.setData({
        summaryPageShow: false
      })
    },
    getFileIcon(fileName: string) {
      let icon = 'def-icon'
      const matchArr = fileName.match(/\.([^.]+)$/)
      if (matchArr && matchArr[1]) {
        const ext = matchArr[1].toLocaleLowerCase()
        switch(ext) {
          case 'pdf':
            icon = 'pdf-icon'
            break;
          case 'doc':
          case 'docx':
            icon = 'word-icon'
            break;
          case 'xls':
          case 'xlsx':
          case 'csv':
            icon = 'excel-icon'
            break;
          case 'txt':
            icon = 'txt-icon'
            break;
          case 'ris':
            icon = 'ris-icon'
            break;
          case 'ppt':
          case 'pptx':
            icon = 'ppt-icon'
            break;
          default:
            icon = 'def-icon'
            break;
        }
      }
      return icon
    },
    resetDirObj(dir: any) {
      if (dir.children && dir.children.length) {
        dir.children.forEach((cd: any) => {
          this.resetDirObj(cd)
        })
      } else {
        delete dir.children
      }
    },
    /**
     * 根据文件夹获取文件列表
     */
    async getDirFileList () {
      this.data.fileList = []
      this.data.dirList = this.data.dirList || []
      const params = {
        uid: parseInt(this.data.uid), 
        dir_id: this.data.currentDirItem.dir_id
      }
      console.log('调用getDirFileList接口，参数:', params);
      const data = await api.getDirFileList(params)
      if (data.files && data.files.length) {
        data.files.forEach((file: any) => {
          file.icon = this.getFileIcon(file.file_name)
        })
        this.data.fileList = data.files
      }
      if (!this.data.currentDirItem.dir_id && data.directories && data.directories.length) {
        this.data.dirList = [{dir_id: '', dir_name: '所有文件夹'}].concat(data.directories)
        this.data.dirList.forEach((dir: any) => {
          this.resetDirObj(dir)
        })
      }
      this.setData({
        fileList: this.data.fileList,
        dirList: this.data.dirList,
      })
    },
    /**
     * 移动文件选择文件夹弹窗
     */
    handlePopSelectDirMove(e: BaseEvent) {
      const index = e.currentTarget.dataset.index
      const file = this.data.fileList[index]
      this.data.currentFile = file
      this.data.isChangeDir = false
      this.setData({
        selectDirShow: true
      })
    },
    /**
     * 选择文件夹切换文件列表弹窗
     */
    handlePopChangeDir() {
      this.data.isChangeDir = true
      this.setData({
        selectDirShow: true
      })
    },
    /**
     * 文件夹选择
     * @param e
     */
    handleSelectDirChange(e: BaseEvent) {
      const selectItem = e.detail.selectedOptions[e.detail.selectedOptions.length-1]
      this.data.cacheCurrentDirItem = selectItem
    },
    /**
     * 关闭文件夹选择弹框
     */
    handleSelectDirClose() {
      this.setData({
        selectDirShow: false
      })
    },
    /**
     * 选择文件夹确定
     */
    handleSelectDirConfirm() {
      if (this.data.isChangeDir) {
        this.setData({
          currentDirItem: this.data.cacheCurrentDirItem,
          selectDirShow: false
        })
        this.getDirFileList()
      } else {
        this.moveFile()
      }
    },
    /**
     * 移动文件
     */
    async moveFile() {
      wx.showLoading({
        title: '加载中'
      })
      try {
        const res = await api.fileMoveTo({
          uid: this.data.uid,
          file_id: this.data.currentFile.id,
          target_path_id: this.data.cacheCurrentDirItem.dir_id,
        })
        wx.hideLoading()
        if (res.status === 'success') {
          wx.showToast({
            title: '文件移动成功',
            icon: 'success'
          })
          this.handleSelectDirClose()
          this.getDirFileList()
        } else {
          wx.showToast({
            title: res.message || '文件移动失败',
            icon: 'error'
          })
        }
      } catch(e){
        wx.hideLoading()
        wx.showToast({
          title: '文件移动异常',
          icon: 'error'
        })
        console.log(e)
      }
    },
    /**
     * 删除文件
     * @param e
     */
    handleDeleteFile(e: BaseEvent) {
      const index = e.currentTarget.dataset.index
      const file = this.data.fileList[index]
      wx.showModal({
        title: '提示',
        content: `确定要删除文件${file.file_name}吗?`,
        success: async (res) => {
          if (res.confirm) {
            try {
              const res = await api.deleteFile({
                uid: this.data.uid,
                file_id: file.id
              })
              if (res.status === 'success') {
                wx.showToast({
                  title: '文件删除成功',
                  icon: 'success'
                })
                this.getDirFileList()
              } else {
                wx.showToast({
                  title: '文件删除失败',
                  icon: 'error'
                })
              }
            } catch(e){

            }

          } else if (res.cancel) {
            console.log('用户点击取消')
          }
        }
      })
    },
    async getFileUrl(fileId: string) {
      let url = ''
      try {
        const res = await api.getFileUrl({
          uid: this.data.uid,
          file_id: fileId
        })
        if (res.access_url) {
          url = envConfig.apiBase + res.access_url.replace(/.*?(?=\/private_knowledge)/, '')
        }
      } catch (e) {}
      return url
    },
    async openFileByIndex(index: number) {
      const file = this.data.fileList[index]
      if (!file) return
      const fileType = (file.file_type || '').toLowerCase()
      if (fileType !== 'pdf' && fileType !== 'word') {
        return
      }
      wx.showLoading({
        title: '加载中'
      })
      const url = await this.getFileUrl(file.id)
      if (!url) {
        wx.hideLoading()
        wx.showToast({
          title: '文件地址获取失败',
          icon: 'error'
        })
        return
      }
      wx.downloadFile({
        url,
        success: function (res) {
          const filePath = res.tempFilePath
          wx.hideLoading()
          wx.openDocument({
            filePath: filePath,
            success: function (res) {
              console.log('文件打开成功')
            },
            fail: function () {
              wx.showToast({
                title: '文件打开失败',
                icon: 'error'
              })
            }
          })
        },
        fail: function () {
          wx.hideLoading()
          wx.showToast({
            title: '文件下载失败',
            icon: 'error'
          })
        }
      })
    },
    /**
     * 使用微信查看文件
     * @param e
     */
    async handleViewFile(e: BaseEvent) {
      const index = e.currentTarget.dataset.index
      await this.openFileByIndex(index)
    },
    handleDialogueClick(e: BaseEvent) {
      const index = e.currentTarget.dataset.index
      const file = this.data.fileList[index]
      this.setData({
        dialogueSheetShow: true,
        dialogueFile: file,
        activeDialogueModel: this.data.activeDialogueModel || this.data.dialogueModelList[0],
        dialogueTopicId: '',
        dialogueChatHistory: [],
        dialogueQuestion: '',
        dialogueScrollIntoView: '',
        dialogueMode: 'file',
        dialogueFolderFileIds: []
      })
    },
    handleCloseDialogueSheet() {
      this.setData({
        dialogueSheetShow: false,
        dialogueFile: null,
        dialogueUploads: [],
        dialogueQuestion: '',
        dialogueChatHistory: [],
        dialogueTopicId: '',
        dialogueScrollIntoView: '',
        dialogueMode: 'file',
        dialogueFolderFileIds: []
      })
    },
    handleFolderDialogue() {
      const folderName = this.data.currentDirItem?.dir_name || '全部目录';
      const folderId = this.data.currentDirItem?.dir_id || '';
      this.setData({
        dialogueSheetShow: true,
        dialogueFile: { title: `${folderName} · 文件夹`, file_id: folderId },
        activeDialogueModel: this.data.activeDialogueModel || this.data.dialogueModelList[0],
        dialogueTopicId: '',
        dialogueChatHistory: [],
        dialogueQuestion: '',
        dialogueScrollIntoView: '',
        dialogueMode: 'folder',
        dialogueFolderFileIds: (this.data.fileList || [])
          .map((item: any) => item?.id)
          .filter((id: string) => !!id)
      })
    },
    onDialogueModelSelect(e: BaseEvent) {
      const model = e.currentTarget.dataset.model
      this.setData({
        activeDialogueModel: model
      })
    },
    handleDialogueConditionToggle(e: BaseEvent) {
      const code = e.currentTarget.dataset.code
      if (!code) return
      const status = { ...this.data.dialogueConditionStatus }
      status[code] = status[code] ? 0 : 1
      this.setData({
        dialogueConditionStatus: status
      })
    },
    handleDialogueInput(e: any) {
      this.setData({
        dialogueQuestion: e.detail.value
      })
    },
    handleDialogueUpload() {
      const remaining = 3 - this.data.dialogueUploads.length
      if (remaining <= 0) {
        wx.showToast({ title: '最多上传3个文件', icon: 'none' })
        return
      }
      wx.chooseMessageFile({
        count: remaining,
        type: 'file',
        success: (res) => {
          const files = (res.tempFiles || []).map((file: any) => {
            const extension = (file.name.split('.').pop() || '').toUpperCase()
            return {
              name: file.name,
              extension: extension || 'FILE'
            }
          })
          this.setData({
            dialogueUploads: this.data.dialogueUploads.concat(files)
          })
        }
      })
    },
    handleDialogueRemoveFile(e: BaseEvent) {
      const index = Number(e.currentTarget.dataset.index)
      if (Number.isNaN(index)) return
      const list = [...this.data.dialogueUploads]
      list.splice(index, 1)
      this.setData({
        dialogueUploads: list
      })
    },
    async handleStartDialogue() {
      const question = (this.data.dialogueQuestion || '').trim()
      const fileId = this.data.dialogueFile?.id || this.data.dialogueFile?.file_id
      if (!question) {
        wx.showToast({ title: '请输入内容', icon: 'none' })
        return
      }

      if (this.data.dialogueMode === 'folder') {
        await this.startFolderDialogue(question)
        return
      }

      if (!fileId) {
        wx.showToast({ title: '未找到文件信息', icon: 'none' })
        return
      }

      wx.showLoading({ title: '对话中', mask: true })
      try {
        const quotaMsg = await this.validateDialogueQuota()
        if (quotaMsg) {
          wx.hideLoading()
          wx.showToast({ title: quotaMsg, icon: 'none' })
          return
        }

        let topicId = this.data.dialogueTopicId
        if (!topicId) {
          const topicRes: any = await api.createTopic({
            uid: this.data.uid,
            search_text: this.data.dialogueFile?.title || question
          })
          topicId = topicRes?.topic_id || ''
          this.setData({ dialogueTopicId: topicId })
        }

        if (!topicId) {
          wx.hideLoading()
          wx.showToast({ title: '对话创建失败', icon: 'error' })
          return
        }

        const dialogueId = createDialogueId(`${this.data.uid}:${topicId}:${Date.now()}`, 12)
        const chatItem = common.getDefChatItem()
        chatItem.dialogue_id = dialogueId
        chatItem.user = question
        chatItem.topicId = topicId
        chatItem.status = ChatStatusEnum.Start
        const chatHistory = [chatItem, ...this.data.dialogueChatHistory]
        this.setData({
          dialogueChatHistory: chatHistory,
          dialogueQuestion: '',
          dialogueScrollIntoView: dialogueId
        })

        const params = {
          uid: this.data.uid || 430,
          file_id: fileId,
          chat_text: question,
          topic_id: topicId,
          dialogue_id: dialogueId
        }

        api.chat('/aispire/file_read/chat', params, chatItem, {
          reasonCall: () => {
            chatItem.reasoningObj = app.towxml(chatItem.reasoning, 'markdown', { theme: 'reason' })
            this.updateDialogueChatItem(chatItem)
          },
          answerCall: () => {
            chatItem.aispireObj = app.towxml(chatItem.aispire, 'markdown', { theme: 'answer' })
            this.updateDialogueChatItem(chatItem)
          },
          completeCall: () => {
            chatItem.loading = false
            chatItem.finish = true
            chatItem.status = ChatStatusEnum.Stop
            this.updateDialogueChatItem(chatItem)
            wx.hideLoading()
          },
          errorCall: () => {
            chatItem.loading = false
            chatItem.finish = true
            chatItem.status = ChatStatusEnum.Stop
            chatItem.aispire = '对话失败，请稍后重试'
            chatItem.aispireObj = app.towxml(chatItem.aispire, 'markdown', { theme: 'answer' })
            this.updateDialogueChatItem(chatItem)
            wx.hideLoading()
            wx.showToast({ title: '对话失败，请稍后重试', icon: 'none' })
          }
        })
      } catch (error) {
        console.error('文献对话失败:', error)
        wx.hideLoading()
        wx.showToast({ title: '对话失败，请稍后重试', icon: 'none' })
      }
    },
    async startFolderDialogue(question: string) {
      const fileIds = this.data.dialogueFolderFileIds || []
      if (!fileIds.length) {
        wx.showToast({ title: '当前目录暂无文件', icon: 'none' })
        return
      }
      wx.showLoading({ title: '对话中', mask: true })
      try {
        const dialogueId = createDialogueId(`${this.data.uid}:${Date.now()}`, 12)
        const chatItem = common.getDefChatItem()
        chatItem.dialogue_id = dialogueId
        chatItem.user = question
        chatItem.topicId = ''
        chatItem.status = ChatStatusEnum.Start
        const chatHistory = [chatItem, ...this.data.dialogueChatHistory]
        this.setData({
          dialogueChatHistory: chatHistory,
          dialogueQuestion: '',
          dialogueScrollIntoView: dialogueId
        })

        const params = {
          uid: this.data.uid || 430,
          file_ids: fileIds,
          chat_text: question
        }

        api.chat('/aispire/dir_op/dir_chat', params, chatItem, {
          reasonCall: () => {
            chatItem.reasoningObj = app.towxml(chatItem.reasoning, 'markdown', { theme: 'reason' })
            this.updateDialogueChatItem(chatItem)
          },
          answerCall: () => {
            chatItem.aispireObj = app.towxml(chatItem.aispire, 'markdown', { theme: 'answer' })
            this.updateDialogueChatItem(chatItem)
          },
          completeCall: () => {
            chatItem.loading = false
            chatItem.finish = true
            chatItem.status = ChatStatusEnum.Stop
            this.updateDialogueChatItem(chatItem)
            wx.hideLoading()
          },
          errorCall: () => {
            chatItem.loading = false
            chatItem.finish = true
            chatItem.status = ChatStatusEnum.Stop
            chatItem.aispire = '对话失败，请稍后重试'
            chatItem.aispireObj = app.towxml(chatItem.aispire, 'markdown', { theme: 'answer' })
            this.updateDialogueChatItem(chatItem)
            wx.hideLoading()
            wx.showToast({ title: '对话失败，请稍后重试', icon: 'none' })
          }
        })
      } catch (error) {
        console.error('文件夹对话失败:', error)
        wx.hideLoading()
        wx.showToast({ title: '对话失败，请稍后重试', icon: 'none' })
      }
    },
    /**
     * 卡片点击
     */
    async handleCardTap(e: BaseEvent) {
      const index = e.currentTarget.dataset.index
      await this.openFileByIndex(index)
    },
    /**
     * 从微信聊天记录选择文件上传
     */
    handleChooseFile() {
      let extension: string[] = []
      let url = ''
      wx.showActionSheet({
        itemList: ['pdf文件上传','word文件上传','txt文件上传','ppt文件上传','excel文件上传','markdown文件上传'],
        success: (res) => {
          switch(res.tapIndex) {
            case 0:
              extension = ['pdf']
              url = envConfig.apiBase + '/aispire/file_op/pdf_upload'
              break;
            case 1:
              extension = ['doc', '.docx']
              url = envConfig.apiBase + '/aispire/file_op/word_upload'
              break;
            case 2:
              extension = ['txt']
              url = envConfig.apiBase + 'aispire/file_op/txt_upload'
              break;
            case 3:
              extension = ['ppt', 'pptx']
              url = envConfig.apiBase + '/aispire/file_op/ppt_upload'
              break;
            case 4:
              extension = ['xls', 'xlsx', 'csv']
              url = envConfig.apiBase + '/aispire/file_op/excel_upload'
              break;
            case 5:
              extension = ['md', 'markdown']
              url = envConfig.apiBase + '/aispire/file_op/markdown_upload'
              break;
          }
          const getUploadTask = (file) => {
            return wx.uploadFile({
              url,
              filePath: file.path,
              name: 'files',
              formData: {
                uid: this.data.uid,
                parent_dir_id: this.data.currentDirItem.dir_id,
                name: file.name
              },
              success (res){
                const data = res.data
                console.log('文件上传成功', data)
              }
            })
          }
          wx.chooseMessageFile({
            count: 10,  // 选择10个文件
            type: 'file',
            extension,
            success: (res) => {
              if (url) {
                wx.showLoading({
                  title: '文件上传解析中'
                })
                const tasks = []
                const size = res.tempFiles.length
                for (let i = 0; i < size; i++) {
                  const file = res.tempFiles[i]
                  const p = getUploadTask(file)
                  tasks.push(p)
                }
                Promise.all(tasks).then(() => {
                  wx.hideLoading()
                  wx.showToast({
                    title: '文件上传成功',
                    icon: 'success'
                  })
                  this.getDirFileList()
                }).catch((e) => {
                  wx.hideLoading()
                })
                /*
                wx.uploadFile({
                  url,
                  filePath: file.path,
                  name: 'files',
                  formData: {
                    uid: this.data.uid,
                    parent_dir_id: this.data.currentDirItem.dir_id,
                    name: file.name
                  },
                  success: (res) => {
                    wx.hideLoading()
                    let data = {}
                    try {
                      data = JSON.parse(res.data)
                    } catch(e){}
                    if (data.status === 'success') {
                      wx.showToast({
                        title: '文件上传成功',
                        icon: 'success'
                      })
                      this.getDirFileList()
                    } else {
                      wx.showToast({
                        title: '文件上传失败',
                        icon: 'error'
                      })
                    }
                  },
                  complete() {
                    wx.hideLoading()
                  }
                })
                 */
              }
            }
          });
        },
      })
    },
    async getImportantDirs() {
      try {
        const res = await api.getImportantDirs({ uid: this.data.uid });
        if (res && res.status === 'success' && res.data) {
          this.setData({ importantDirs: res.data.slice(0, 5) });
        }
      } catch (error) {
        console.error('获取常用文件夹失败:', error);
      }
    },
    handleImportantDirClick(e) {
      const { dir_id, dir_name } = e.currentTarget.dataset;
      console.log('点击常用文件夹:', { dir_id, dir_name });
      console.log('dataset:', e.currentTarget.dataset);
      
      // 更新当前选中的文件夹
      this.setData({
        currentDirItem: { dir_id, dir_name },
        selectDirShow: false
      });
      
      // 重新获取文件列表，传入正确的参数格式
      this.getDirFileListWithDirId(dir_id);
    },
    
    /**
     * 根据指定文件夹ID获取文件列表
     */
    async getDirFileListWithDirId(dirId) {
      this.data.fileList = [];
      this.data.dirList = this.data.dirList || [];
      
      // 使用正确的参数格式：uid为数字，dir_id为字符串
      const params = {
        uid: parseInt(this.data.uid), 
        dir_id: dirId
      };
      
      console.log('调用getDirFileList接口，参数:', params);
      
      const data = await api.getDirFileList(params);
      
      if (data.files && data.files.length) {
        data.files.forEach((file) => {
          file.icon = this.getFileIcon(file.file_name);
        });
        this.data.fileList = data.files;
      }
      
      if (!dirId && data.directories && data.directories.length) {
        this.data.dirList = [{dir_id: '', dir_name: '全部目录'}].concat(data.directories);
        this.data.dirList.forEach((dir) => {
          this.resetDirObj(dir);
        });
      }
      
      this.setData({
        fileList: this.data.fileList,
        dirList: this.data.dirList,
      });
    },
    async validateDialogueQuota(): Promise<string> {
      try {
        const res: any = await api.checkUserQuota({ uid: this.data.uid })
        if (this.data.dialogueConditionStatus.r1 && res?.high_model_exceeded) {
          return 'DeepSeek R1 今日次数已用完'
        }
        if (!this.data.dialogueConditionStatus.r1 && res?.regular_model_exceeded) {
          return '模型今日次数已用完'
        }
        if (this.data.dialogueConditionStatus.knowledge && res?.my_knowledge_base_exceeded) {
          return '【搜智库】今日次数已用完'
        }
        if (this.data.dialogueConditionStatus.aispire && res?.aispire_knowledge_base_exceeded) {
          return '【搜AISPIRE】今日次数已用完'
        }
        if (this.data.dialogueConditionStatus.network && res?.online_search_exceeded) {
          return '【搜全网】今日次数已用完'
        }
        return ''
      } catch (error) {
        console.error('配额校验失败:', error)
        return '配额校验失败，请稍后重试'
      }
    },
    updateDialogueChatItem(chatItem: ChatItemType) {
      const index = this.data.dialogueChatHistory.findIndex(item => item.dialogue_id === chatItem.dialogue_id)
      if (index === -1) return
      this.setData({
        [`dialogueChatHistory[${index}]`]: chatItem,
        dialogueScrollIntoView: chatItem.dialogue_id
      })
    }
  },
})
